/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.library.entityDAO;

import cz.library.database.Database;
import cz.library.entity.Kniha;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Lattis
 */
public class KnihaDAO extends TableDAO implements DAO<Kniha> {

    private static final String TABLE_NAME = "LIB_KNIHA";
    private static final String FIND_ALL = "SELECT * FROM LIB_KNIHA";
    private static final String FIND_BY_ID = "SELECT * FROM LIB_KNIHA WHERE ID_KNIHA = ?";
    private static final String FIND_BY_NAZEV = "SELECT * FROM LIB_KNIHA WHERE NAZEV = ?";
    private static final String SELECT_ID = "SELECT ID_KNIHA FROM LIB_KNIHA";
    private static final String INSERT = "INSERT INTO LIB_KNIHA(NAZEV,VYDANI,ID_NAKLADATELSTVI) VALUES(?,?,?)";
    private static final String DELETE = "DELETE FROM LIB_KNIHA WHERE ID_KNIHA = ?";
    private static final String SELECT_NAZEV = "SELECT NAZEV FROM LIB_KNIHA";
    private Connection mConnection;

    public KnihaDAO(Database database) {
        super(database, TABLE_NAME);
        mConnection = database.Connection();
    }

    public List<Kniha> findAll() {

        List<Kniha> listKniha = new ArrayList<Kniha>();
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {
            pstm = mConnection.prepareStatement(FIND_ALL);
//            st.start();
            rs = pstm.executeQuery();
            while (rs.next()) {
                listKniha.add(new Kniha(rs.getInt(1), rs.getString(2),
                        rs.getInt(3), rs.getInt(4)));
            }
//            st.stop();
//            System.err.println(st.getElapsedTime());
        } catch (SQLException e) {
            System.err.println(e);
            listKniha = null;
        } finally {
            close(rs, pstm);
            return listKniha;
        }
    }

    public Kniha findByNazev(String nazev) {
        PreparedStatement pstm = null;
        ResultSet rs = null;
        Kniha kniha = null;
        try {
            pstm = mConnection.prepareStatement(FIND_BY_NAZEV);
            pstm.setString(1, nazev);
            rs = pstm.executeQuery();
            while (rs.next()) {
                kniha = new Kniha(rs.getInt(1), rs.getString(2), rs.getInt(3), rs.getInt(4));
            }
        } catch (SQLException e) {
            kniha = null;
        } finally {
            close(rs, pstm);
            return kniha;
        }
    }

    public Kniha findById(int id) {
        PreparedStatement pstm = null;
        ResultSet rs = null;
        Kniha kniha = null;
        try {
            pstm = mConnection.prepareStatement(FIND_BY_ID);
            pstm.setInt(1, id);
            rs = pstm.executeQuery();
            while (rs.next()) {
                kniha = new Kniha(rs.getInt(1), rs.getString(2), rs.getInt(3), rs.getInt(4));
            }
        } catch (SQLException e) {
            kniha = null;
        } finally {
            close(rs, pstm);
            return kniha;
        }
    }

    public boolean insert(Kniha entity) {
        PreparedStatement pstm = null;
        boolean ret = false;
        int rownum = 0;
        try {
            pstm = mConnection.prepareStatement(INSERT);
            pstm.setString(1, entity.getNazev());
            pstm.setInt(2, entity.getVydani());
            pstm.setInt(3, entity.getNakladatelstvi());
            mDatabase.BeginTransaction();
            mConnection.setTransactionIsolation(mConnection.TRANSACTION_READ_COMMITTED);
            rownum = pstm.executeUpdate();
            if (rownum != 0) {
                ret = false;
            }
        } catch (SQLException e) {
            mDatabase.Rollback();
//            System.err.println("KnihaInsert ROLLBACK > "+ e.getMessage());
            ret = false;
        } finally {
            mDatabase.EndTransaction();
            close(null, pstm);
            return ret;
        }
    }

    public boolean delete(Kniha entity) {
        PreparedStatement pstm = null;
        boolean ret = false;
        try {
            pstm = mConnection.prepareStatement(DELETE);
            pstm.setInt(1, entity.getId_kniha());

            mDatabase.BeginTransaction();
            mConnection.setTransactionIsolation(mConnection.TRANSACTION_SERIALIZABLE);
            if (!pstm.execute()) {
                ret = true;
            }
        } catch (SQLException ex) {
            mDatabase.Rollback();
            ret = false;
        } finally {
            mDatabase.EndTransaction();
            close(null, pstm);
            return ret;
        }
    }

    public boolean update(Kniha entity) {
        throw new UnsupportedOperationException("Not supported yet.");
//         mConnection.setTransactionIsolation(mConnection.TRANSACTION_READ_COMMITTED);
    }

    public void close(ResultSet rs, PreparedStatement pstm) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (pstm != null) {
                pstm.close();
            }
        } catch (Exception e) {
            System.err.println("Closing Error");
        }
    }

    public List<Kniha> read(ResultSet rs) throws SQLException {
        List<Kniha> listKniha = new ArrayList<Kniha>();
        while (rs.next()) {
            Kniha k = new Kniha(rs.getInt(1), rs.getString(2), rs.getInt(3), rs.getInt(4));
            listKniha.add(k);
        }
        return listKniha;
    }

    public List<Integer> getDictId() {
        List<Integer> listId = new ArrayList<Integer>();
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {
            pstm = mConnection.prepareStatement(SELECT_ID);
            rs = pstm.executeQuery();
            while (rs.next()) {
                listId.add(rs.getInt("id_kniha"));
            }
        } catch (SQLException e) {
            listId = null;
        } finally {
            close(rs, pstm);
            return listId;
        }
    }

    public List<String> getDictNazev() {
        List<String> listNazev = new ArrayList<String>();

        PreparedStatement pstm = null;
        ResultSet rs = null;

        try {
            pstm = mConnection.prepareStatement(SELECT_NAZEV);
            rs = pstm.executeQuery();

            while (rs.next()) {
                listNazev.add(rs.getString("prijmeni"));
            }
        } catch (SQLException ex) {
            listNazev = null;
        } finally {
            close(rs, pstm);
            return listNazev;
        }
    }
}
